﻿using System;
using System.Text;
using Forms=TheClerk.Forms;

namespace TheClerk.Counter
{
    /// <summary>
    /// The interface for transaction processing, including recording
    /// </summary>
    /// <remarks>
    /// The idea here is that the Clerk keeps -everything-.
    /// 
    /// The thing that makes this Clerk better than real clerks is that it
    /// can archive old revisions.  (The capabilities of Raven make this
    /// insanely easy.)
    /// 
    /// The Clerk does not fulfill any request without a Form.
    /// 
    /// And the Clerk does not recognize the sovereignty of the State, only
    /// the sovereignty of its Principal.
    /// </remarks>
    public static class Clerk
    {
        public static Forms.Receipt Submit(Forms.Form submission)
        {
            try
            {
                if (false == submission.isComplete)
                    throw new Forms.FormNotCompleteException();
            }
            catch (Exception e)
            {
                UserInterface.WarnUser("Could not record Form: " +
                    submission.ToString());
                throw new ApplicationException("Submission failed", e);
            }
            return ReceiveForm(submission);
        }

        /// <summary>
        /// Initiates the process of acting on a Form
        /// </summary>
        /// <param name="submission">the filled-out form to be recorded</param>
        private static Forms.Receipt ReceiveForm(Forms.Form submission)
        {
            // FIXME Replace ApplicationException

            if (submission == null)
                throw new ArgumentNullException("submission");
            if (!submission.isComplete)
                throw new ApplicationException("Form has not been completed");
            Forms.Receipt r = Forms.Form.CreateReceipt(submission);
            // Build a new Receipt object from submission, which
            // is the serialized submission plus a timestamp, all of which is
            // signed by Clerk.
            return r;
        }

        /// <summary>
        /// Gets the form (i.e., object that encapsulates a request) id'd by a given String
        /// </summary>
        /// <param name="submission">A String which identifies the Form to obtain</param>
        /// <returns>serial-numbered instance of Form</returns>
        public static Forms.Form GetForm(String submission)
        {
            Forms.Form requested = null;
            // TODO: finish this
            return new Forms.GenericForm();
        }
    }
}